import functools
import json
import re
import threading
from configparser import ConfigParser

from code_analysis.aiapi import AiApi
from data_store.sqlite_api import SqliteApi
from concurrent.futures import ThreadPoolExecutor


class Analyzer:
    def __init__(self):
        self.conf = ConfigParser()
        self.conf.read('./config/config.ini')
        self.api_key = self.conf['model']['api_key']
        self.base_url = self.conf['model']['base_url']
        self.model = self.conf['model']['model']
        self.ai_api = AiApi(self.api_key, self.base_url, self.model)
        self.sqlite_api = SqliteApi()
        self.pool = ThreadPoolExecutor(max_workers=8, thread_name_prefix='code_analysis')

    def run(self, code_chunks):
        for file, code_chunk in code_chunks.items():
            print('send file:{file} to pool'.format(file=file))
            future = self.pool.submit(self.extract_json_from_response, code_chunk)
            future.add_done_callback(self.call_back)

    def call_back(self, future):
        responses = future.result()
        for res in responses:
            self.sqlite_api.insert_one_record(
                res
            )

    def send_code_chunk(self, code_chunk):
        response = self.ai_api.send_aliyun_model(code_chunk)
        message = json.loads(response)['choices'][0]['message']
        content = message['content']
        return content

    def extract_json_from_response(self, code_chunk):
        responses = []
        for code in code_chunk:
            if not code:
                continue
            thread_name = threading.current_thread().name
            print("当前线程的名字是：", thread_name)
            code_position = '{thread_name}-{file}-{start}-{end}'.format(thread_name=thread_name, file=code[-1], start=code[0][0], end=code[1][0])
            print(code_position)
            response = self.send_code_chunk(code)
            json_pattern = re.compile(r'\{.*?\}', re.DOTALL)
            matches = json_pattern.findall(response)
            # 尝试解析第一个匹配的 JSON 字符串
            for match in matches:
                try:
                    json_response = json.loads(match)
                    # 检查是否符合预期格式
                    if all(key in json_response for key in
                           ['encryption', 'decryption', 'signature', 'verification', 'hash', 'algorithm', 'analysis']):
                        json_response['code'] = code_position
                        responses.append(json_response)
                except json.JSONDecodeError:
                    continue
        return responses


if __name__ == '__main__':
    code_trunk = 'npublic static byte[] SM3HashMac(String text,String key){\n        //1.填充0至key,或者hashkey,使其长度为sm3分组长度\n        /** ' \
                 'BLOCK_LENGTHSM3分组长度 ,64个字节,512位*/\n        byte[] sm3_key;\n        byte[] structured_key=new byte[BLOCK_LENGTH];\n        ' \
                 'byte[] IPAD=new byte[BLOCK_LENGTH];\n        byte[] OPAD=new byte[BLOCK_LENGTH];\n        if(StringUtil.base64Decode(' \
                 'key).length>BLOCK_LENGTH){\n            sm3_key= sm3Hash(StringUtil.base64Decode(key));\n            System.arraycopy(sm3_key,' \
                 '0,structured_key,0,sm3_key.length);\n        }else {\n            System.arraycopy(StringUtil.base64Decode(key),0,' \
                 'structured_key,0,StringUtil.base64Decode(key).length);\n        }\n        //2.让处理之后的key 与ipad (分组长度的0x36)做异或运算\n        for(' \
                 'int i=0;i<BLOCK_LENGTH;i++){\n            IPAD[i]=0x36;\n            OPAD[i]=0x5c;\n        }\n        byte[] ipadkey=XOR(' \
                 'structured_key,IPAD);\n        //3.将2的结果与text拼接\n        int textLen=text.getBytes().length;\n        byte[] t3=new byte[' \
                 'BLOCK_LENGTH+textLen];\n        System.arraycopy(ipadkey,0,t3,0,ipadkey.length);\n        System.arraycopy(text.getBytes(),0,' \
                 't3,ipadkey.length,text.getBytes().length);\n        //4.将3的结果sm3 哈希\n        byte[] t4=sm3Hash(t3);\n        //5.让处理之后的key ' \
                 '与opad(分组长度的0x5c)做异或运算\n        byte[] opadkey=XOR(structured_key,OPAD);\n        //6.4的结果拼接在5之后\n        byte[] t6=new byte[' \
                 'BLOCK_LENGTH+t4.length];\n        System.arraycopy(opadkey,0,t6,0,opadkey.length);\n        System.arraycopy(t4,0,t6,' \
                 'opadkey.length,t4.length);\n        //7.对6做hash\n        return (sm3Hash(t6));\n    }\n'

    analysis = Analyzer()
    res = analysis.extract_json_from_response(code_trunk)
    print(res)
